package com.otd.exif 
{
	import flash.display.*;
	import flash.net.*;
	import flash.events.*;
	import flash.utils.*;
	import flash.filesystem.FileStream;
	
	public class Exif extends Sprite 
	{
		private var image:URLLoader = null;
				
		public function Exif( path:String = "YOUR_DEFAULT_TEST_FILE" ) 
		{						
			/*
			var request:URLRequest = new URLRequest( path );
			
			image = new URLLoader();
			image.dataFormat = DataFormat.BINARY;
			image.addEventListener( EventType.COMPLETE, parse );
			image.load( request );
			*/
		}		
		
		public function parse( io:FileStream ):Array 
		{
			var contents:Array = new Array();
			var ifddata:Array = null;
			var dump:Array = null;
			var ifd:Array = null;
			var data:ByteArray = new ByteArray();
			var exif:uint = 0;
			var interop:uint = 0;
			var length:uint = 0;
			var tiff:TIFF = null;
			var info:Info = null;
			
			io.readBytes( data, 0, 12 );
			
			if( !isJpeg( data ) || !hasExif( data ) ) 
			{
				// trace( "Not a JPEG containing EXIF data." );
				return null;	
			}
			
			data.position = 4;
			length = data.readUnsignedShort();
			// trace( "EXIF header length: " + length + " bytes" );
			contents.push( new Info( "-", "Length", length.toString() ) );
			
			io.readBytes( data, 0, length - 8 );
			
			if( data[0] == 73 ) 
			{
				// trace( "Intel format" );	
				contents.push( new Info( "-", "Format", "Intel" ) );				
			} else {
				// trace( "Motorola format" );
				contents.push( new Info( "-", "Format", "Motorola" ) );				
			}
			
			tiff = new TIFF( data );
			ifd = tiff.list();
			
			for( var i:int = 0; i < ifd.length; i++ ) 
			{
				// trace( "IFD " + i );
				
				if( i == 0 ) 
				{
					// trace( "Main image" );	
				} else if( i == 1 ) {
					// trace( "Thumbnail image" );	
				}
				
				// trace( "At offset: " + ifd[i] );
				
				// contents = tiff.dump( ifd[i] );
				// tiff.print( contents, TIFF.EXIF_TAGS );
				ifddata = tiff.dump( ifd[i] );
				contents = contents.concat( tiff.print( ifddata, TIFF.EXIF_TAGS ) );
				
				exif = 0;
				
				for( var t:int = 0; t < ifddata.length; t++ ) 
				{
					if( IFD( ifddata[t] ).tag == 34665 ) 
					{
						exif = IFD( ifddata[t] ).values[0];
					}
				}
				
				if( exif != 0 ) 
				{
					// trace( "Exif SubIFD at offset " + exif );	
					// contents = tiff.dump( exif );
					// tiff.print( contents, TIFF.EXIF_TAGS );
					ifddata = tiff.dump( exif );
					contents = contents.concat( tiff.print( ifddata, TIFF.EXIF_TAGS ) );
					
					interop = 0;
					
					for( var s:int = 0; s < ifddata.length; s++ ) 
					{
						if( IFD( ifddata[s] ).tag == 40965 ) 
						{
							interop = IFD( ifddata[s] ).values[0];
						}	
					}

					if( interop != 0 ) 
					{
						// trace( "Exif Interoperability SubSubIFD at offset " + interop );
						// contents = tiff.dump( interop );
						// tiff.print( contents, TIFF.INTEROP_TAGS );	
						ifddata = tiff.dump( interop );
						contents = contents.concat( tiff.print( ifddata, TIFF.EXIF_TAGS ) );
					}					
				}
			}
			
			return contents;
		}
		
		public function isJpeg( data:ByteArray ):Boolean 
		{
			var jpeg:Boolean = false;
			
			if( data[0] == 255 && data[1] == 216 &&
				data[2] == 255 && data[3] == 225 ) 
			{
				jpeg = true;	
			}
			
			return jpeg;
		}
		
		public function hasExif( data:ByteArray ):Boolean 
		{
			var exif:Boolean = false;

			if( data[6] == 69 && data[7] == 120 &&
				data[8] == 105 && data[9] == 102 ) 
			{
				exif = true;		
			}
			
			return exif;	
		}
	}
}